import { Sprite as PIXISprite,Texture} from "pixi.js";
import {TexturePool} from "@/utils/TexturePool.js";
import { ImageManager } from "@/managers/ImageManager.js";
import { ToneFilter } from "@/filters/ToneFilter.js";
import { ScreenFilter } from "@/filters/ScreenFilter";

export class Sprite extends PIXISprite {
    /**
     * @param {TextureSource} source 
     */
    constructor(source) {
        let texture=Texture.EMPTY;
        if(source){
            texture=TexturePool.newTexture(source);
        }
        super(texture);
        
        this.texture.noFrame=false;

        /**
         * @type {ToneFilter}
         */
        this.toneFilter=null;
        /**
         * @type {ScreenFilter}
         */
        this.blendFilter=null;
    }

    destroy(opts){
        if(this.destroyed)return;
        opts=opts||{children:true};
        if(opts.texture){
            opts.texture=false;
        }
        if(opts.textureSource){
            opts.textureSource=false;
        }

        this.releaseTexture();
        super.destroy(opts);
    }

    releaseTexture(){
        let texture=this.texture;
        this.texture=Texture.EMPTY;
        this.releaseTextureSource(texture._source);
        TexturePool.releaseTexture(texture);
    }

    releaseTextureSource(source){
        ImageManager.releaseUnknowImageSource(source);
    }

    noSource(){return this._texture._source.label=='EMPTY';}

    set source(value){
        if(this.texture._source==value){
            ImageManager.releaseUnknowImageSource(value);
            return;
        }
        if(!value){
            if(this.texture.label=='EMPTY')return;
            this.releaseTexture();
        }else{
            let texture=this.texture;
            if(texture.label=='EMPTY'){
                texture=TexturePool.newTexture(value);
                this.texture=texture;
            }else{
                this._changeSource(value);
            }
        }
    }
    get source(){
        return this._texture._source;
    }

    get opacity() {
        return this.alpha * 255;
    }

    set opacity(value) {
        this.alpha = value/255;
    }

    update() {
        for(let child of this.children){
            child.update?.();
        }
    }

    move(x, y) {
        this.x = x;
        this.y = y;
    }

    setFrame(x, y, width, height) {
        if(this.source.label=='EMPTY')return;
        let frame=this._texture.frame;
        if(frame.x!=x||frame.y!=y||frame.width!=width||frame.height!=height){
            frame.x=x;
            frame.y=y;
            frame.width=width;
            frame.height=height;
            this.texture.updateUvs();
            this.onViewUpdate();
        }
        
    }
    /**
     * @private
     */
    _changeSource(source){
        if(!source)return;
        let oldSource=this.texture._source;
        if(oldSource.label=='EMPTY')return;
        this.texture.source=source;
        
        this.updateTexture();

        source.off('resize',this.texture.update,this.texture);

        this.releaseTextureSource(oldSource);
    }

    updateTexture(){
        this.texture.noFrame=true;
        this.texture.update();
        this.texture.noFrame=false;
    }

    setBlendColor(color){
        if(color[0]!=0||color[1]!=0||color[2]!=0){
            if(!this.blendFilter){
                this.blendFilter=new ScreenFilter();
                if(!this.filters){
                    this.filters=[];
                }
                this.filters.push(this.blendFilter);
            }else{
                this.blendFilter.enabled=true;
            }
            this.blendFilter.setTone(...color);
        }else{
            this.blendFilter.enabled=false;
        }
    }
    getBlendColor(){
        return this.blendFilter.getTone();
    }

    setColorTone(tone){
        if(color[0]!=0||color[1]!=0||color[2]!=0){
            if(!this.toneFilter){
                this.toneFilter=new ToneFilter();
                if(!this.filters){
                    this.filters=[];
                }
                this.filters.push(this.toneFilter);
            }else{
                this.toneFilter.enabled=true;
            }
            this.toneFilter.setTone(tone[0]/255,tone[1]/255,tone[2]/255);
        }else{
            this.toneFilter.enabled=false;
        }
    }

    getColorTone() {
        let tone=this.toneFilter.tone;
        return [tone[0]*255,tone[1]*255,tone[2]*255,0];
    }
}